/*
uart_rx
#(
	.P_CLK_FRE(50),      //clock frequency(Mhz)
	.P_BAUD_RATE(BAUD_RATE) //serial baud rate
)
uart_rx(
	.i_clk(clk_50M),                 //clock input
	.i_rst_n(rst_n),                //asynchronous reset input, low active 
	.i_rx_data_ready(1'b1),         //input wire rx_data_ready
	.i_rx_pin(rx_pin),              //input wire rx_pin,
	.o_rx_data(rx_data),            //output wire [7:0] rx_data;
	.o_rx_data_valid(rx_data_valid) //output wire rx_data_valid;
);
*/
module uart_rx
#(
	parameter 		P_CLK_FRE = 50,      //clock frequency(Mhz)
	parameter 		P_BAUD_RATE = 115200 //serial baud rate
)
(
	input           i_clk,                //clock input                                
	input           i_rst_n,             //asynchronous reset input, low active        
	input           i_rx_data_ready,     //input wire i_rx_data_ready                    
	input           i_rx_pin,            //input wire i_rx_pin,                          
    output [7:0]	o_rx_data,           //output wire [7:0] o_rx_data;                  
	output          o_rx_data_valid      //output wire o_rx_data_valid;                  
);
//calculates the clock P_CYCLE for baud rate 
localparam                       P_CYCLE = P_CLK_FRE * 1000000 / P_BAUD_RATE;
//state machine code
localparam                       S_IDLE      = 0;
localparam                       S_START     = 1; //start bit
localparam                       S_REC_BYTE  = 2; //data bits
localparam                       S_STOP      = 3; //stop bit
localparam                       S_DATA      = 4;

reg[2:0]                         state;
reg[2:0]                         next_state;
reg                              r_rx_d0;            //delay 1 clock for i_rx_pin
reg                              r_rx_d1;            //delay 1 clock for r_rx_d0
reg[7:0]                         r_rx_bits;          //temporary storage of received data
reg[15:0]                        r_cycle_cnt;        //baud counter
reg[2:0]                         r_bit_cnt;          //bit counter
reg [7:0]                        r_rx_data;
reg                              r_rx_data_valid;
wire                             w_rx_negedge;       //negedge of i_rx_pin
assign w_rx_negedge = r_rx_d1 && ~r_rx_d0;

always@(posedge i_clk or negedge i_rst_n)
begin
	if(i_rst_n == 1'b0)
	begin
		r_rx_d0 <= 1'b0;
		r_rx_d1 <= 1'b0;	
	end
	else
	begin
		r_rx_d0 <= i_rx_pin;
		r_rx_d1 <= r_rx_d0;
	end
end


always@(posedge i_clk or negedge i_rst_n)
begin
	if(i_rst_n == 1'b0)
		state <= S_IDLE;
	else
		state <= next_state;
end

always@(*)
begin
	case(state)
		S_IDLE:
			if(w_rx_negedge)
				next_state <= S_START;
			else
				next_state <= S_IDLE;
		S_START:
			if(r_cycle_cnt == P_CYCLE - 1)//one data cycle 
				next_state <= S_REC_BYTE;
			else
				next_state <= S_START;
		S_REC_BYTE:
			if(r_cycle_cnt == P_CYCLE - 1  && r_bit_cnt == 3'd7)  //receive 8bit data
				next_state <= S_STOP;
			else
				next_state <= S_REC_BYTE;
		S_STOP:
			if(r_cycle_cnt == P_CYCLE/2 - 1)//half bit cycle,to avoid missing the next byte receiver
				next_state <= S_DATA;
			else
				next_state <= S_STOP;
		S_DATA:
			if(i_rx_data_ready)    //data receive complete
				next_state <= S_IDLE;
			else
				next_state <= S_DATA;
		default:
			next_state <= S_IDLE;
	endcase
end

always@(posedge i_clk or negedge i_rst_n)
begin
	if(i_rst_n == 1'b0)
		r_rx_data_valid <= 1'b0;
	else if(state == S_STOP && next_state != state)
		r_rx_data_valid <= 1'b1;
	else if(state == S_DATA && i_rx_data_ready)
		r_rx_data_valid <= 1'b0;
end
assign o_rx_data_valid = r_rx_data_valid;

always@(posedge i_clk or negedge i_rst_n)
begin
	if(i_rst_n == 1'b0)
		r_rx_data <= 8'd0;
	else if(state == S_STOP && next_state != state)
		r_rx_data <= r_rx_bits;//latch received data
    else
        r_rx_data <= r_rx_data;
end
assign o_rx_data = r_rx_data;

always@(posedge i_clk or negedge i_rst_n)
begin
	if(i_rst_n == 1'b0)
		begin
			r_bit_cnt <= 3'd0;
		end
	else if(state == S_REC_BYTE)
		if(r_cycle_cnt == P_CYCLE - 1)
			r_bit_cnt <= r_bit_cnt + 3'd1;
		else
			r_bit_cnt <= r_bit_cnt;
	else
		r_bit_cnt <= 3'd0;
end

always@(posedge i_clk or negedge i_rst_n)
begin
	if(i_rst_n == 1'b0)
		r_cycle_cnt <= 16'd0;
	else if((state == S_REC_BYTE && r_cycle_cnt == P_CYCLE - 1) || next_state != state)
		r_cycle_cnt <= 16'd0;
	else
		r_cycle_cnt <= r_cycle_cnt + 16'd1;	
end
//receive serial data bit data
always@(posedge i_clk or negedge i_rst_n)
begin
	if(i_rst_n == 1'b0)
		r_rx_bits <= 8'd0;
	else if(state == S_REC_BYTE && r_cycle_cnt == P_CYCLE/2 - 1)
		r_rx_bits[r_bit_cnt] <= i_rx_pin;
	else
		r_rx_bits <= r_rx_bits; 
end

endmodule 